#pragma once

#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
#include <optional>
#include "viml/value_fwd.h"

namespace viml {
    // 前向声明以避免循环包含
    class Value;
}

namespace viml {

/**
 * 源码位置信息
 */
struct SourceLocation {
    std::string file;        // 源文件名
    int line;               // 行号
    int column;             // 列号

    SourceLocation(const std::string& f = "", int l = 0, int c = 0)
        : file(f), line(l), column(c) {}

    bool is_valid() const { return !file.empty() && line > 0; }
    std::string to_string() const;
};

/**
 * 变量位置信息
 */
struct VariableInfo {
    std::string name;               // 变量名
    SourceLocation location;        // 声明位置
    std::string scope;              // 作用域（local, global, script等）
    size_t register_index;          // 寄存器索引（如果适用）
    size_t start_pc;                // 作用域起始PC
    size_t end_pc;                  // 作用域结束PC

    VariableInfo(const std::string& n = "", const SourceLocation& loc = SourceLocation(),
                 const std::string& s = "local", size_t reg = 0, size_t start = 0, size_t end = 0)
        : name(n), location(loc), scope(s), register_index(reg), start_pc(start), end_pc(end) {}
};

/**
 * 函数信息
 */
struct FunctionInfo {
    std::string name;               // 函数名
    SourceLocation location;        // 定义位置
    std::vector<std::string> params; // 参数列表
    size_t start_pc;                // 函数起始地址
    size_t end_pc;                  // 函数结束地址
    std::vector<VariableInfo> locals; // 局部变量信息

    FunctionInfo(const std::string& n = "", const SourceLocation& loc = SourceLocation(),
                 size_t start = 0, size_t end = 0)
        : name(n), location(loc), start_pc(start), end_pc(end) {}
};

/**
 * 断点信息
 */
struct BreakpointInfo {
    size_t id;                      // 断点ID
    SourceLocation location;        // 断点位置
    size_t pc;                      // 对应的程序计数器
    bool enabled;                   // 是否启用
    std::string condition;           // 条件表达式（可选）
    int hit_count;                  // 命中次数
    int ignore_count;               // 忽略次数

    BreakpointInfo(size_t i = 0, const SourceLocation& loc = SourceLocation(),
                   size_t pc_addr = 0, bool en = true)
        : id(i), location(loc), pc(pc_addr), enabled(en), hit_count(0), ignore_count(0) {}
};

/**
 * 调试信息管理器
 *
 * 负责管理调试所需的所有元数据，包括：
 * - 源码行号到字节码地址的映射
 * - 变量位置和作用域信息
 * - 函数定义信息
 * - 断点管理
 */
class DebugInfo {
private:
    std::string source_file;                    // 源文件路径
    std::vector<std::string> source_lines;      // 源码行

    // 行号映射
    std::unordered_map<int, size_t> line_to_pc;  // 行号 -> PC
    std::unordered_map<size_t, int> pc_to_line;  // PC -> 行号

    // 函数信息
    std::unordered_map<std::string, FunctionInfo> functions;
    std::vector<std::string> function_order;      // 函数定义顺序

    // 变量信息
    std::vector<VariableInfo> variables;         // 所有变量信息

    // 断点管理
    std::unordered_map<size_t, BreakpointInfo> breakpoints;
    std::unordered_map<int, size_t> line_breakpoints; // 行号 -> 断点ID
    size_t next_breakpoint_id;

    // 当前执行上下文信息
    std::vector<std::string> call_stack;         // 当前调用栈
    std::unordered_map<std::string, Value> variable_values; // 当前变量值

public:
    DebugInfo(const std::string& filename = "");
    ~DebugInfo() = default;

    // 禁用拷贝构造和赋值
    DebugInfo(const DebugInfo&) = delete;
    DebugInfo& operator=(const DebugInfo&) = delete;

    // 源码管理
    void set_source_file(const std::string& filename);
    bool load_source_file();
    const std::string& get_source_file() const { return source_file; }
    const std::vector<std::string>& get_source_lines() const { return source_lines; }
    std::string get_source_line(int line) const;
    int get_line_count() const { return static_cast<int>(source_lines.size()); }

    // 行号映射
    void add_line_mapping(int line, size_t pc);
    size_t pc_for_line(int line) const;
    int line_for_pc(size_t pc) const;
    SourceLocation get_location(size_t pc) const;
    bool has_line_mapping(int line) const;
    bool has_pc_mapping(size_t pc) const;

    // 函数信息管理
    void add_function(const FunctionInfo& func);
    void add_function(const std::string& name, const SourceLocation& location,
                     size_t start_pc, size_t end_pc,
                     const std::vector<std::string>& params = {});
    const FunctionInfo* get_function(const std::string& name) const;
    const FunctionInfo* get_function_at_pc(size_t pc) const;
    std::vector<std::string> get_function_names() const;
    std::vector<const FunctionInfo*> get_functions_in_range(size_t start_pc, size_t end_pc) const;

    // 变量信息管理
    void add_variable(const VariableInfo& var);
    void add_variable(const std::string& name, const SourceLocation& location,
                     const std::string& scope, size_t register_index,
                     size_t start_pc, size_t end_pc);
    const VariableInfo* get_variable(const std::string& name) const;
    std::vector<const VariableInfo*> get_variables_at_pc(size_t pc) const;
    std::vector<const VariableInfo*> get_variables_in_scope(size_t pc, const std::string& function_name = "") const;
    std::vector<const VariableInfo*> get_local_variables(const std::string& function_name) const;

    // 断点管理
    size_t add_breakpoint(int line, const std::string& condition = "");
    size_t add_breakpoint(const SourceLocation& location, const std::string& condition = "");
    size_t add_breakpoint(size_t pc, const std::string& condition = "");
    bool remove_breakpoint(size_t breakpoint_id);
    bool remove_breakpoint(int line);
    bool enable_breakpoint(size_t breakpoint_id, bool enabled = true);
    bool disable_breakpoint(size_t breakpoint_id);
    const BreakpointInfo* get_breakpoint(size_t breakpoint_id) const;
    const BreakpointInfo* get_breakpoint_at_line(int line) const;
    const BreakpointInfo* get_breakpoint_at_pc(size_t pc) const;
    std::vector<const BreakpointInfo*> get_all_breakpoints() const;
    std::vector<const BreakpointInfo*> get_enabled_breakpoints() const;
    bool has_breakpoint_at_line(int line) const;
    bool has_breakpoint_at_pc(size_t pc) const;
    void clear_all_breakpoints();

    // 断点命中处理
    bool should_break(size_t pc, const std::unordered_map<std::string, Value>& variables);
    void hit_breakpoint(size_t breakpoint_id);
    void set_breakpoint_condition(size_t breakpoint_id, const std::string& condition);
    void set_breakpoint_ignore_count(size_t breakpoint_id, int ignore_count);

    // 执行上下文管理
    void set_call_stack(const std::vector<std::string>& stack);
    const std::vector<std::string>& get_call_stack() const { return call_stack; }
    void update_variable_value(const std::string& name, const Value& value);
    Value get_variable_value(const std::string& name) const;
    const std::unordered_map<std::string, Value>& get_variable_values() const { return variable_values; }
    void clear_variable_values();

    // 调试信息查询
    std::vector<SourceLocation> get_executable_locations() const;
    std::vector<int> get_executable_lines() const;
    bool is_executable_line(int line) const;
    bool is_valid_pc(size_t pc) const;

    // 函数上下文查询（供Debugger使用）
    std::string extract_function_context(size_t pc) const;

    // 格式化和输出
    std::string format_location(const SourceLocation& location) const;
    std::string format_breakpoint(const BreakpointInfo& bp) const;
    std::string format_function(const FunctionInfo& func) const;
    std::string format_variable(const VariableInfo& var) const;

    // 统计信息
    struct DebugStatistics {
        size_t total_functions = 0;
        size_t total_variables = 0;
        size_t total_breakpoints = 0;
        size_t enabled_breakpoints = 0;
        size_t total_line_mappings = 0;
    };

    DebugStatistics get_statistics() const;

    // 清理和重置
    void clear();
    void reset();

private:
    // 内部辅助方法
    size_t generate_breakpoint_id() { return next_breakpoint_id++; }
    bool evaluate_breakpoint_condition(const std::string& condition,
                                    const std::unordered_map<std::string, Value>& variables) const;
    void update_line_breakpoint_map();
};

} // namespace viml